/* SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * Copyright:
 *   2020      Evan Nemerson <evan@nemerson.com>
 *   2020      Hidayat Khan <huk2209@gmail.com>
 */

#define SIMDE_TEST_X86_AVX512_INSN mulhi

#include <test/x86/avx512/test-avx512.h>
#include <simde/x86/avx512/mulhi.h>

static int
test_simde_mm512_mulhi_epi16 (SIMDE_MUNIT_TEST_ARGS) {
  static const struct {
    const int16_t a[32];
    const int16_t b[32];
    const int16_t r[32];
  } test_vec[] = {
    { { -INT16_C( 16752),  INT16_C(  3096),  INT16_C( 21789),  INT16_C( 27232), -INT16_C( 17038),  INT16_C( 13798), -INT16_C(  6599), -INT16_C( 28056),
        -INT16_C( 14632),  INT16_C( 22925), -INT16_C( 11459),  INT16_C( 11763),  INT16_C( 13417),  INT16_C( 15127),  INT16_C(  4707), -INT16_C(  3144),
        -INT16_C( 12079), -INT16_C(  4353),  INT16_C( 24613), -INT16_C( 26792),  INT16_C( 15901),  INT16_C( 22476),  INT16_C( 13349), -INT16_C(   535),
         INT16_C( 30459),  INT16_C( 14422),  INT16_C( 18761), -INT16_C( 19867),  INT16_C( 31870), -INT16_C(  7698), -INT16_C( 22898),  INT16_C( 24533) },
      { -INT16_C( 11145), -INT16_C( 25523), -INT16_C( 22988),  INT16_C( 21044),  INT16_C(   228),  INT16_C(  2473), -INT16_C( 28107),  INT16_C( 12294),
         INT16_C( 23560),  INT16_C( 20840), -INT16_C( 12890),  INT16_C(  9220), -INT16_C(  3511), -INT16_C( 10491), -INT16_C(  9576),  INT16_C(  3895),
        -INT16_C( 31569), -INT16_C(  7252), -INT16_C(  8150),  INT16_C(  3893), -INT16_C(  8480),  INT16_C(  5400),  INT16_C(  8048),  INT16_C( 30789),
        -INT16_C( 21125),  INT16_C(  8650), -INT16_C( 12678), -INT16_C( 15547),  INT16_C( 19392),  INT16_C( 22683), -INT16_C( 11739), -INT16_C( 11160) },
      {  INT16_C(  2848), -INT16_C(  1206), -INT16_C(  7643),  INT16_C(  8744), -INT16_C(    60),  INT16_C(   520),  INT16_C(  2830), -INT16_C(  5264),
        -INT16_C(  5261),  INT16_C(  7289),  INT16_C(  2253),  INT16_C(  1654), -INT16_C(   719), -INT16_C(  2422), -INT16_C(   688), -INT16_C(   187),
         INT16_C(  5818),  INT16_C(   481), -INT16_C(  3061), -INT16_C(  1592), -INT16_C(  2058),  INT16_C(  1851),  INT16_C(  1639), -INT16_C(   252),
        -INT16_C(  9819),  INT16_C(  1903), -INT16_C(  3630),  INT16_C(  4713),  INT16_C(  9430), -INT16_C(  2665),  INT16_C(  4101), -INT16_C(  4178) } },
    { {  INT16_C(  5206), -INT16_C( 32328), -INT16_C(  4620), -INT16_C( 11120), -INT16_C( 22324),  INT16_C( 15594),  INT16_C( 12231),  INT16_C( 17333),
         INT16_C( 32733),  INT16_C( 22372), -INT16_C( 21939),  INT16_C(  3355), -INT16_C( 18699),  INT16_C(  6757), -INT16_C( 12920), -INT16_C(  8465),
        -INT16_C( 22559), -INT16_C( 10913), -INT16_C(  4204),  INT16_C( 24746), -INT16_C( 27496),  INT16_C( 24477),  INT16_C( 21187), -INT16_C( 24414),
         INT16_C(  2001),  INT16_C(  7928),  INT16_C(  5041), -INT16_C( 22997), -INT16_C( 28471),  INT16_C( 20928), -INT16_C( 20642),  INT16_C( 16175) },
      { -INT16_C( 28842), -INT16_C(  5355), -INT16_C( 16514),  INT16_C(  5707), -INT16_C(  6061),  INT16_C(  5750),  INT16_C(  6202),  INT16_C(  2999),
        -INT16_C( 20705), -INT16_C( 12247),  INT16_C( 21698), -INT16_C( 29834),  INT16_C( 14309),  INT16_C( 17372),  INT16_C(  3046),  INT16_C( 15746),
        -INT16_C( 26726),  INT16_C(  6440),  INT16_C( 29526), -INT16_C( 22225), -INT16_C( 23204), -INT16_C( 26944),  INT16_C( 30654), -INT16_C(  8798),
        -INT16_C( 13530), -INT16_C(  5970),  INT16_C(  9248),  INT16_C(  1395),  INT16_C( 20315),  INT16_C( 16968), -INT16_C( 13734), -INT16_C(  2689) },
      { -INT16_C(  2292),  INT16_C(  2641),  INT16_C(  1164), -INT16_C(   969),  INT16_C(  2064),  INT16_C(  1368),  INT16_C(  1157),  INT16_C(   793),
        -INT16_C( 10342), -INT16_C(  4181), -INT16_C(  7264), -INT16_C(  1528), -INT16_C(  4083),  INT16_C(  1791), -INT16_C(   601), -INT16_C(  2034),
         INT16_C(  9199), -INT16_C(  1073), -INT16_C(  1895), -INT16_C(  8393),  INT16_C(  9735), -INT16_C( 10064),  INT16_C(  9910),  INT16_C(  3277),
        -INT16_C(   414), -INT16_C(   723),  INT16_C(   711), -INT16_C(   490), -INT16_C(  8826),  INT16_C(  5418),  INT16_C(  4325), -INT16_C(   664) } },
    { { -INT16_C( 22686), -INT16_C( 18418),  INT16_C( 15642),  INT16_C( 30306),  INT16_C(  8931), -INT16_C( 24307), -INT16_C( 20583), -INT16_C( 16514),
         INT16_C( 11386), -INT16_C( 25945),  INT16_C(  6737), -INT16_C( 21345), -INT16_C(  6295), -INT16_C( 15378),  INT16_C( 28082),  INT16_C(  5304),
        -INT16_C( 14828),  INT16_C( 12236),  INT16_C( 11780), -INT16_C(  6235), -INT16_C( 19888), -INT16_C(  5752),  INT16_C(  1633), -INT16_C(  9048),
         INT16_C( 20275), -INT16_C( 31626),  INT16_C(  5737), -INT16_C( 11728),  INT16_C(  8189), -INT16_C( 20586),  INT16_C( 20108), -INT16_C( 24125) },
      { -INT16_C( 28651),  INT16_C(  6608),  INT16_C( 30142),  INT16_C(  3840), -INT16_C( 30680), -INT16_C( 30216), -INT16_C( 24178), -INT16_C( 16027),
        -INT16_C(  8976),  INT16_C( 23109),  INT16_C( 30450), -INT16_C(  4308), -INT16_C( 15723),  INT16_C(  8607),  INT16_C( 25105),  INT16_C(  9922),
        -INT16_C( 27918), -INT16_C( 20161),  INT16_C( 16136),  INT16_C( 12480), -INT16_C( 18233),  INT16_C( 21945),  INT16_C(  8025),  INT16_C( 18967),
         INT16_C( 23803), -INT16_C(  4700), -INT16_C( 12078),  INT16_C( 26588),  INT16_C( 31635), -INT16_C( 23415),  INT16_C( 19422), -INT16_C( 12086) },
      {  INT16_C(  9917), -INT16_C(  1858),  INT16_C(  7194),  INT16_C(  1775), -INT16_C(  4181),  INT16_C( 11206),  INT16_C(  7593),  INT16_C(  4038),
        -INT16_C(  1560), -INT16_C(  9149),  INT16_C(  3130),  INT16_C(  1403),  INT16_C(  1510), -INT16_C(  2020),  INT16_C( 10757),  INT16_C(   803),
         INT16_C(  6316), -INT16_C(  3765),  INT16_C(  2900), -INT16_C(  1188),  INT16_C(  5533), -INT16_C(  1927),  INT16_C(   199), -INT16_C(  2619),
         INT16_C(  7363),  INT16_C(  2268), -INT16_C(  1058), -INT16_C(  4759),  INT16_C(  3952),  INT16_C(  7355),  INT16_C(  5959),  INT16_C(  4449) } },
    { {  INT16_C(  2526), -INT16_C(  6527),  INT16_C( 16712),  INT16_C(  3862), -INT16_C( 12294),  INT16_C( 21348),  INT16_C( 31726), -INT16_C(  5731),
         INT16_C( 16856), -INT16_C( 21802), -INT16_C( 19694), -INT16_C( 23278), -INT16_C( 25810),  INT16_C(  3145),  INT16_C(  5094), -INT16_C( 15139),
         INT16_C( 24092),  INT16_C( 25770), -INT16_C( 16224), -INT16_C( 25997), -INT16_C( 10352),  INT16_C( 32493), -INT16_C( 29869),  INT16_C( 11112),
         INT16_C( 16076), -INT16_C(  8491), -INT16_C(  6159),  INT16_C(  8323), -INT16_C( 13182),  INT16_C( 26924),  INT16_C(  2527), -INT16_C(  1235) },
      { -INT16_C( 10136),  INT16_C(  2143), -INT16_C( 11624),  INT16_C( 10402), -INT16_C( 28758), -INT16_C(   601),  INT16_C(  3866), -INT16_C(  6360),
        -INT16_C(   691),  INT16_C( 16325),  INT16_C( 18917),  INT16_C( 26463), -INT16_C( 29931), -INT16_C(  2608), -INT16_C(   363), -INT16_C(   528),
         INT16_C( 20694),  INT16_C( 28165), -INT16_C( 22750), -INT16_C( 13161),  INT16_C( 15926),  INT16_C( 20937), -INT16_C(  3763), -INT16_C( 26056),
        -INT16_C(   529), -INT16_C( 11047),  INT16_C( 14406),  INT16_C( 23611),  INT16_C(  3268),  INT16_C( 22865),  INT16_C( 16650), -INT16_C(  8106) },
      { -INT16_C(   391), -INT16_C(   214), -INT16_C(  2965),  INT16_C(   612),  INT16_C(  5394), -INT16_C(   196),  INT16_C(  1871),  INT16_C(   556),
        -INT16_C(   178), -INT16_C(  5431), -INT16_C(  5685), -INT16_C(  9400),  INT16_C( 11787), -INT16_C(   126), -INT16_C(    29),  INT16_C(   121),
         INT16_C(  7607),  INT16_C( 11075),  INT16_C(  5631),  INT16_C(  5220), -INT16_C(  2516),  INT16_C( 10380),  INT16_C(  1715), -INT16_C(  4418),
        -INT16_C(   130),  INT16_C(  1431), -INT16_C(  1354),  INT16_C(  2998), -INT16_C(   658),  INT16_C(  9393),  INT16_C(   642),  INT16_C(   152) } },
    { {  INT16_C( 23441), -INT16_C( 19378), -INT16_C(  6910),  INT16_C( 14464),  INT16_C( 18979),  INT16_C( 28809), -INT16_C( 16069),  INT16_C( 10763),
        -INT16_C(  6977),  INT16_C(  1534),  INT16_C( 14877), -INT16_C(  7839), -INT16_C( 19898),  INT16_C( 20538), -INT16_C( 28428), -INT16_C( 31440),
         INT16_C( 32491), -INT16_C(  4807), -INT16_C( 17820), -INT16_C( 30939), -INT16_C( 20732),  INT16_C( 16376),  INT16_C(   880),  INT16_C( 12138),
         INT16_C( 26855),  INT16_C(  1077), -INT16_C( 26974), -INT16_C(  5915),  INT16_C(  8009),  INT16_C( 15672),  INT16_C( 26799), -INT16_C( 25918) },
      { -INT16_C(   793),  INT16_C( 19335), -INT16_C( 21066), -INT16_C( 17710), -INT16_C( 13732), -INT16_C( 13063),  INT16_C( 25549), -INT16_C( 18948),
         INT16_C( 12748),  INT16_C( 28345), -INT16_C( 24633),  INT16_C(  4183), -INT16_C( 28738),  INT16_C( 28237),  INT16_C(  4344), -INT16_C(  8440),
        -INT16_C( 28660), -INT16_C( 15830), -INT16_C(   963), -INT16_C( 26244),  INT16_C( 30151), -INT16_C( 27547),  INT16_C( 25049), -INT16_C( 23223),
         INT16_C(   914),  INT16_C( 23059),  INT16_C( 27298),  INT16_C( 24682), -INT16_C( 18182), -INT16_C(  3378), -INT16_C( 10296), -INT16_C( 11055) },
      { -INT16_C(   284), -INT16_C(  5718),  INT16_C(  2221), -INT16_C(  3909), -INT16_C(  3977), -INT16_C(  5743), -INT16_C(  6265), -INT16_C(  3112),
        -INT16_C(  1358),  INT16_C(   663), -INT16_C(  5592), -INT16_C(   501),  INT16_C(  8725),  INT16_C(  8849), -INT16_C(  1885),  INT16_C(  4048),
        -INT16_C( 14209),  INT16_C(  1161),  INT16_C(   261),  INT16_C( 12389), -INT16_C(  9539), -INT16_C(  6884),  INT16_C(   336), -INT16_C(  4302),
         INT16_C(   374),  INT16_C(   378), -INT16_C( 11236), -INT16_C(  2228), -INT16_C(  2222), -INT16_C(   808), -INT16_C(  4211),  INT16_C(  4372) } },
    { { -INT16_C(  1177), -INT16_C( 23402),  INT16_C(  4855), -INT16_C( 16835), -INT16_C( 23929),  INT16_C( 24659), -INT16_C( 25596), -INT16_C( 27131),
         INT16_C(  6559),  INT16_C( 16880),  INT16_C( 23427),  INT16_C( 32162),  INT16_C( 28691), -INT16_C(  9361),  INT16_C( 16455), -INT16_C( 20817),
         INT16_C( 17723),  INT16_C( 13138), -INT16_C( 28841), -INT16_C(  8463),  INT16_C( 17458),  INT16_C( 13887),  INT16_C( 17633), -INT16_C( 32564),
        -INT16_C( 17059), -INT16_C(  7742),  INT16_C( 25624),  INT16_C( 11102), -INT16_C( 12588),  INT16_C(  7174), -INT16_C( 19186),  INT16_C( 19146) },
      {  INT16_C(  7674),  INT16_C( 20861),  INT16_C( 28332), -INT16_C(  8657),  INT16_C( 28339), -INT16_C( 27628), -INT16_C(  7757),  INT16_C(  4116),
        -INT16_C( 10594), -INT16_C( 18703),  INT16_C( 20538),  INT16_C(  4065), -INT16_C(  6370),  INT16_C( 11307), -INT16_C(  2660), -INT16_C( 27018),
        -INT16_C(  3310), -INT16_C( 16409),  INT16_C(  5730),  INT16_C(  5533), -INT16_C( 19835),  INT16_C( 14505), -INT16_C( 17005),  INT16_C( 12616),
         INT16_C( 14996), -INT16_C( 12569), -INT16_C( 14198), -INT16_C( 22307),  INT16_C(  2223),  INT16_C( 19412),  INT16_C( 19454),  INT16_C(  4321) },
      { -INT16_C(   138), -INT16_C(  7450),  INT16_C(  2098),  INT16_C(  2223), -INT16_C( 10348), -INT16_C( 10396),  INT16_C(  3029), -INT16_C(  1704),
        -INT16_C(  1061), -INT16_C(  4818),  INT16_C(  7341),  INT16_C(  1994), -INT16_C(  2789), -INT16_C(  1616), -INT16_C(   668),  INT16_C(  8582),
        -INT16_C(   896), -INT16_C(  3290), -INT16_C(  2522), -INT16_C(   715), -INT16_C(  5284),  INT16_C(  3073), -INT16_C(  4576), -INT16_C(  6269),
        -INT16_C(  3904),  INT16_C(  1484), -INT16_C(  5552), -INT16_C(  3779), -INT16_C(   427),  INT16_C(  2124), -INT16_C(  5696),  INT16_C(  1262) } },
    { { -INT16_C( 14274), -INT16_C( 24369),  INT16_C( 28126),  INT16_C( 25525),  INT16_C( 24095), -INT16_C( 19813), -INT16_C(  7140), -INT16_C( 20253),
        -INT16_C( 13794), -INT16_C( 22402),  INT16_C( 23698),  INT16_C( 16720),  INT16_C(  9316),  INT16_C( 25228),  INT16_C( 28015), -INT16_C( 20877),
         INT16_C( 16949),  INT16_C(  4942),  INT16_C(  1199), -INT16_C( 12681),  INT16_C(  4706),  INT16_C( 32384),  INT16_C( 25590),  INT16_C(  5166),
        -INT16_C( 21203), -INT16_C( 16452),  INT16_C(  3081),  INT16_C( 27904), -INT16_C( 29647), -INT16_C( 24368),  INT16_C( 17401),  INT16_C( 11854) },
      { -INT16_C( 25211),  INT16_C( 13634), -INT16_C( 18015),  INT16_C(   771), -INT16_C( 31541), -INT16_C( 15742), -INT16_C( 20249),  INT16_C(  5590),
        -INT16_C( 27811),  INT16_C( 26324), -INT16_C( 10849), -INT16_C( 12076), -INT16_C( 23455),  INT16_C( 23409), -INT16_C( 16409),  INT16_C( 27785),
        -INT16_C( 13476), -INT16_C(   607), -INT16_C( 23164),  INT16_C( 20481), -INT16_C( 31959),  INT16_C(  4114), -INT16_C(  6093), -INT16_C( 28379),
        -INT16_C(  1413),  INT16_C(  7159), -INT16_C( 13361),  INT16_C( 12523),  INT16_C( 23663),  INT16_C( 22155),  INT16_C(  5404),  INT16_C( 30915) },
      {  INT16_C(  5491), -INT16_C(  5070), -INT16_C(  7732),  INT16_C(   300), -INT16_C( 11597),  INT16_C(  4759),  INT16_C(  2206), -INT16_C(  1728),
         INT16_C(  5853), -INT16_C(  8999), -INT16_C(  3924), -INT16_C(  3081), -INT16_C(  3335),  INT16_C(  9011), -INT16_C(  7015), -INT16_C(  8852),
        -INT16_C(  3486), -INT16_C(    46), -INT16_C(   424), -INT16_C(  3964), -INT16_C(  2295),  INT16_C(  2032), -INT16_C(  2380), -INT16_C(  2238),
         INT16_C(   457), -INT16_C(  1798), -INT16_C(   629),  INT16_C(  5332), -INT16_C( 10705), -INT16_C(  8238),  INT16_C(  1434),  INT16_C(  5591) } },
    { {  INT16_C( 25824),  INT16_C( 25974),  INT16_C( 30473),  INT16_C( 12981), -INT16_C( 14342),  INT16_C( 11587),  INT16_C( 26799),  INT16_C( 11198),
        -INT16_C( 18846),  INT16_C( 12614),  INT16_C( 12673), -INT16_C(  3742), -INT16_C(  4722), -INT16_C( 21945),  INT16_C(  2562), -INT16_C(  7390),
        -INT16_C( 26513),  INT16_C( 30792), -INT16_C(   753),  INT16_C(  2475), -INT16_C(  4412),  INT16_C( 29495), -INT16_C(  2730), -INT16_C( 18018),
        -INT16_C(  6997),  INT16_C( 11754),  INT16_C( 19478), -INT16_C( 23522),  INT16_C( 25914),  INT16_C( 15438),  INT16_C( 28784), -INT16_C(  8417) },
      {  INT16_C( 26377),  INT16_C(  6231),  INT16_C(   612),  INT16_C( 10274),  INT16_C( 23024),  INT16_C( 18332),  INT16_C( 14926), -INT16_C(  1536),
        -INT16_C(  5601),  INT16_C( 13607),  INT16_C( 17719),  INT16_C( 29145),  INT16_C( 10154),  INT16_C(  6829), -INT16_C( 12905), -INT16_C( 24327),
         INT16_C( 20788), -INT16_C( 26183), -INT16_C(  9389),  INT16_C( 17601),  INT16_C( 23860), -INT16_C( 32117), -INT16_C( 29800), -INT16_C( 18564),
        -INT16_C( 23691), -INT16_C( 21268), -INT16_C( 14872), -INT16_C( 27875), -INT16_C( 13332), -INT16_C( 31827), -INT16_C( 22632), -INT16_C( 13276) },
      {  INT16_C( 10393),  INT16_C(  2469),  INT16_C(   284),  INT16_C(  2035), -INT16_C(  5039),  INT16_C(  3241),  INT16_C(  6103), -INT16_C(   263),
         INT16_C(  1610),  INT16_C(  2618),  INT16_C(  3426), -INT16_C(  1665), -INT16_C(   732), -INT16_C(  2287), -INT16_C(   505),  INT16_C(  2743),
        -INT16_C(  8410), -INT16_C( 12303),  INT16_C(   107),  INT16_C(   664), -INT16_C(  1607), -INT16_C( 14455),  INT16_C(  1241),  INT16_C(  5103),
         INT16_C(  2529), -INT16_C(  3815), -INT16_C(  4421),  INT16_C( 10004), -INT16_C(  5272), -INT16_C(  7498), -INT16_C(  9941),  INT16_C(  1705) } }
  };

  for (size_t i = 0 ; i < (sizeof(test_vec) / sizeof(test_vec[0])) ; i++) {
    simde__m512i a = simde_mm512_loadu_epi16(test_vec[i].a);
    simde__m512i b = simde_mm512_loadu_epi16(test_vec[i].b);
    simde__m512i r = simde_mm512_mulhi_epi16(a, b);
    simde_test_x86_assert_equal_i16x32(r, simde_mm512_loadu_epi16(test_vec[i].r));
  }

  return 0;
}

SIMDE_TEST_FUNC_LIST_BEGIN
  SIMDE_TEST_FUNC_LIST_ENTRY(mm512_mulhi_epi16)
SIMDE_TEST_FUNC_LIST_END

#include <test/x86/avx512/test-avx512-footer.h>
